﻿using System;
using System.Collections.Generic;
using System.ServiceModel.DomainServices.Client;
using System.Windows.Data;
using Budgetsch.Web.EntityModel;
using Budgetsch.Web.Services;
using GalaSoft.MvvmLight;

namespace Budgetsch.ViewModels
{
    public class IncomesVM : ViewModelBase
    {
        #region Private members

        private readonly BudgetschDomainContext m_context;
        private PagedCollectionView m_incomes = null;
        private bool m_isBusyLoadingIncomes = true;
        private bool m_isBusyLoadingComments = true;
        private bool m_isInMonthMode = true;
        private int m_selectedYear;
        private int m_selectedMonth;

        #endregion

        #region Public properties

        public const string IncomesPropertyName = "Incomes";
        public const string IsBusyLoadingIncomesPropertyName = "IsBusyLoadingIncomes";
        public const string IsBusyLoadingCommentsPropertyName = "IsBusyLoadingComments";

        public PagedCollectionView Incomes
        {
            get
            {
                return m_incomes;
            }

            set
            {
                if (m_incomes == value)
                {
                    return;
                }

                m_incomes = value;
                RaisePropertyChanged(() => Incomes);
            }
        }

        public bool IsBusyLoadingIncomes
        {
            get
            {
                return m_isBusyLoadingIncomes;
            }

            set
            {
                if (m_isBusyLoadingIncomes == value)
                {
                    return;
                }

                m_isBusyLoadingIncomes = value;
                RaisePropertyChanged(() => IsBusyLoadingIncomes);
            }
        }

        public bool IsBusyLoadingComments
        {
            get
            {
                return m_isBusyLoadingComments;
            }

            set
            {
                if (m_isBusyLoadingComments == value)
                {
                    return;
                }

                m_isBusyLoadingComments = value;
                RaisePropertyChanged(() => IsBusyLoadingComments);
            }
        }

        public AddIncomeVM AddIncomeVM { get; set; }

        public IEnumerable<IncomeComment> IncomeComments { get; set; }

        public bool IsInMonthMode
        {
            get { return m_isInMonthMode; }
            set
            {
                m_isInMonthMode = value;
                ChangeTimeframe();
            }
        }

        public int SelectedMonth
        {
            get { return m_selectedMonth; }
            set { m_selectedMonth = value; ChangeTimeframe(); }
        }
        public int SelectedYear
        {
            get { return m_selectedYear; }
            set { m_selectedYear = value; ChangeTimeframe(); }
        }

        #endregion

        public IncomesVM()
        {
            m_context = new BudgetschDomainContext();
            m_context.Load(m_context.GetIncomesForMonthQuery(DateTime.Now.Date.Month), x =>
            {
                IsBusyLoadingIncomes = false;
                Incomes = new PagedCollectionView(m_context.Incomes);
                Incomes.GroupDescriptions.Add(new PropertyGroupDescription("CategoryID"));
            }, new object());
            m_context.Load(m_context.GetIncomeCommentsQuery(), x =>
            {
                IsBusyLoadingComments = false;
            }, new object());
            IncomeComments = m_context.IncomeComments;
            AddIncomeVM = new AddIncomeVM(m_context);
            IsInMonthMode = true;
        }

        #region Public methods

        public void RemoveIncome(object o_)
        {
            var income = o_ as Income;
            if (income != null)
            {
                m_context.Incomes.Remove(income);
            }
            m_context.SubmitChanges();
        }

        public AddIncomeVM GetNewAddIncomeVM()
        {
            return new AddIncomeVM(m_context);
        }

        public EditIncomeVM GetNewIncomeEditorVM(object p)
        {
            var income = p as Income;
            if (p != null)
            {
                return new EditIncomeVM(m_context, income);
            }
            else throw new ArgumentException("Provided object must be an Income item!");
        }

        public void AddCategory(string category_)
        {
            m_context.IncomeCategories.Add(new IncomeCategory() { Name = category_ });
            m_context.SubmitChanges();
        }

        public void RefreshIncomes()
        {
            RaisePropertyChanged(() => Incomes);
        }

        #endregion

        private void ChangeTimeframe()
        {
            IsBusyLoadingIncomes = true;
            m_context.Incomes.Clear();
            if (IsInMonthMode)
            {
                m_context.Load(m_context.GetIncomesForMonthQuery(SelectedMonth), x =>
                {
                    IsBusyLoadingIncomes = false;
                    Incomes = new PagedCollectionView(m_context.Incomes);
                    Incomes.GroupDescriptions.Add(new PropertyGroupDescription("CategoryID"));
                }, new object());
            }
            else
            {
                m_context.Load(m_context.GetIncomesForYearQuery(SelectedYear), x =>
                {
                    IsBusyLoadingIncomes = false;
                    Incomes = new PagedCollectionView(m_context.Incomes);
                    Incomes.GroupDescriptions.Add(new PropertyGroupDescription("CategoryID"));
                }, new object());
            }
        }
    }
}